Scott Lamb commented:
"Measuring police on the absence of crime is even easier to game, with horrible consequences."In more detail, Baruch wrote:
"The result of measuring absence of crime will be that reports of crime will be rejected if the cops will think that they won't be able to catch the criminals. You will have to seperate the group that takes the reports and the group that handles them to make it work and even then I'm not sure someone won't find a way to go around that with another trick."Well, if you read any cycling online forum, you'll have seen some reports of police rejecting reports of 'too hard' crimes like harassing cyclists. I think I've had one report accepted in the last year, about a moped user riding along a cycle track near a playground where I had noted the number plate, and two pretty certainly discarded. So, police discarding or discouraging reports of no-obvious-solution crimes seems to be happening already. andy r wrote:
"Hi there, Don't talk to me about tragedy of targets... As a teacher the word 'target' fills me with both fear and laughter. Last year my year 6 class and I worked our butts off and achieved the highest set of grades for any school in North Somerset, thereby rescuing the school from a very sticky situation with Ofsted. Within days of these results being known the senior LEA advisor suggested to me that the targets had, perhaps, in hindsight been too low. My reply was curt and Anglo-Saxon. Hindsight! Looking out of her hind? The LEA love targets. If you hit them you have not pushed the kids enough. If you exceed them you should have pitched them higher. Woe betide anyone who fails to meet their targets (I will this year, different cohort and those % from last year have been INCREASED!)... My kids have targets (though they have so many that they actually fail to remember them all). Teachers have targets for the numbers of children who are 'supposed' to achieve certain grades but the idiots who set them frequently have only a rudimentary grasp of mathematics. In my current school there are 45 children in a year group, so each one represents a little over 2%. In schools with small classes (perhaps 10 per year in some rural schools) 1 child can equate to 10%. If he's sick on exam day or is just not bright enough, that's 10% gone. And with the government expecting 75-80% of children to achieve a level 4 in their KS2 SATS, it's all too easy to drop blow your 'targets' through illness alone. But here's an even worse tragedy of targets in primary schools... a couple of years ago I had to disapply 2 children from SATS, simply because they have profound special needs and could not take the tests. In addition, the school had an Autistim Unit (now called something PC, but I forget what) which that year had 4 children in year 6. Therefore we had 6 children who could not take the exams. We filled in the paper work but were horrified when the results came in to discover that these children (who all had official exemption on disability grounds) were counted as having taken the test, even though they couldn't. For 'statistical' purposes these kids were classified as having scored zero! Out of a cohort of 36 children, 6 were classified as not having done a thing! The department of education acknowledged that this didn't help our statistics, but stated that it was their policy. In a school with a lot of very deprived kids this 16% scoring zero, added to a significant quanitity of under-achievers was enough to push us down to the bottom 100 primary schools nationally. You can only imagine how damaging that was for the school's reputation - parents took kids out, we were slated in the local press and had to fight like mad to justify our continued existence... Targets... bah! Hey, talking of which. The Health Trust has recently done a survey of local primary school children's weights and heights. In our day this sort of thing was compulsory. Not any more. Parents had to 'opt in' to the survey... And guess what? The parents of the largest kids refused to take part - as did the ignorant b*strds, but that's another story. So the WAHT will now be collating a totally skewed data set. I'm just waiting for the press release highlighting our slim North Somerset children... And of course, someone will be complemented on achieving targets for reducing childhood obesity, whilst infact the problem has probably - as it were- grown. I used to like the way that 'on time targets' were displayed in Didcot railway station. There was a board in foyer which highilighed punctuality. The impressive looking bar chart had these words written on it: "% of trains on time, compared to last month." And the brightly coloured chart was always up around 95%, ish. I was always suprised that nobody commented on that. 0.95*0.95*0.95...... month on month those trains were getting less and less punctual! But nobody bothered to point this out because 95% looks impressive! On many occasions I took the time to read, and re-read, the wording of those graphs so I know with 100% confidence that this was what they quoted. We never had a month with more than 100% punctuality compared to the previous month. Shame. That's enough. I'm off to the dog house."
if (string != null && strong.equals("string"))This quickly becomes tiresome and the test for null distracts from the meaning of the code. Fortunately I was reminded of an improvement for string objects. Ideally, we should all be writing comparison conditionals like rvalue == lvalue. (an rvalue mostly is an expresion you can't assign to). The most common rvalue is a literal value like a string constant. The advantage of getting into the habit of writing code like this is that you'll discover at compile time when you accidentally write = rather than ==. Because you can't assign to an rvalue, the compiler will complain. What makes this interesting from a java string point of view is that you can call methods on string literals. Comparing a variable to a string literal, rather than calling .equals() on a variable is that the string literal is not going to be null, so you can remove the test for null and simplify the code:
if("string".equals(string))I know it's not everyone's cup of tea, but I prefer it to testing for null every time I look at a string. The other thing is that I've been reading Hardcore Java by Robert Simmons at work. Considering I've only got a few pages in so far. I've received a surprisingly large number of ideas to improve my code. The one that sticks in my head is using assert for doing post and pre conditions on your functions. Using asserts have number of advantages over throwing exceptions, including the fact they get optimised away when you do a production release. In Eddie, during a <feed> element I determine the version of Atom that we are parsing. This had a number of nested if/else if/else blocks. At the end of the function, I wanted to make sure I had set the version string to something, so had the following code:
if (!this.feed.has("format")) throw new SAXParseException("Failed to detect Atom format", this.locator);However, using assertions I can write this as
assert(this.feed.has("format")) : "Failed to detect Atom format";I highly recommend the Hardcore java book if you want to improve your java programming. It includes sections on the new features of Java 1.5 and using collections. I've made a couple of other cleanups including going through member variable access specifiers to make sure they are right and making several public methods and variables and making them priavte. I also have a couple of ideas about refactoring some of the code to clean it up. Redesigning and refactoring code is almost more fun than writing it in the first place. You get to be in competition with yourself, challenging yourself to write better code and end up with cleaner code in the process. A couple of things I want to do in the near future is use a profiler and code coverage tools. If anyone has recommendations for either of these tools that integrates nicely with eclipse, I'd love to know.
Note: This article is part of my OS Install Experiences series.Next up: a SUSE 10.1 install. It's been a few years since I touched a SUSE distribution (it was something like SUSE Linux 5.3 or so), a lot has happened since then... Here's a rough sketch of the installation and a few superficial remarks and facts related to security. Install
/etc/passwd
), LDAP, NIS, Windows Domain.uname
and hwinfo
, according to that text. More on that later, maybe...PORT STATE SERVICE 22/tcp open ssh 135/tcp filtered msrpc 137/tcp filtered netbios-ns 138/tcp filtered netbios-dgm 139/tcp filtered netbios-ssn 445/tcp filtered microsoft-ds 1433/tcp filtered ms-sql-s 1434/tcp filtered ms-sql-mNot good. A default install should not have any ports open, IMHO. Quite a bunch of Windows ports, eh? To be fair, if the firewall is enabled, none of those will be reachable.
drwx------ 2 root root 168 2006-05-25 01:50 /.gnupg drwxr-xr-x 3 root root 72 2006-05-25 00:58 /home drwx------ 8 root root 432 2006-05-25 01:56 /root drwxrwxrwt 9 root root 504 2006-05-25 01:55 /tmp crw------- 1 root video 10, 175 May 25 04:58 /dev/agpgart crw-r-----+ 1 root root 5, 1 May 2 08:45 /dev/console drwxr-xr-x 6 root root 120 May 25 04:58 /dev/disk crw-rw---- 1 root video 29, 0 May 25 04:58 /dev/fb0 brw-rw----+ 1 uwe disk 2, 0 May 25 04:58 /dev/fd0 crw--w--w- 1 root root 1, 7 May 25 04:58 /dev/full brw-r----- 1 root disk 3, 0 May 25 04:58 /dev/hda* brw-rw----+ 1 uwe disk 22, 64 May 25 04:58 /dev/hdd crw-r----- 1 root kmem 1, 2 May 25 04:58 /dev/kmem crw-rw---- 1 root root 1, 11 May 2 08:45 /dev/kmsg srw-rw-rw- 1 root root 0 May 25 04:58 /dev/log crw-rw---- 1 root lp 6, 0 May 25 04:58 /dev/lp0 crw-r----- 1 root kmem 1, 1 May 25 04:58 /dev/mem crw-rw-rw- 1 root root 1, 3 May 2 08:45 /dev/null crw-r----- 1 root kmem 1, 4 May 25 04:58 /dev/port crw-rw---- 1 root root 10, 1 May 25 04:58 /dev/psaux crw-rw-rw- 1 root tty 2, 0 May 25 04:58 /dev/ptyp* crw-rw-rw- 1 root root 1, 8 May 25 04:58 /dev/random crw-rw-rw- 1 root tty 5, 0 May 2 08:45 /dev/tty crw--w---- 1 root root 4, 0 May 25 04:58 /dev/tty0 crw-rw---- 1 root tty 4, 2 May 25 04:58 /dev/tty[1-6] crw--w---- 1 uwe tty 4, 7 May 25 04:58 /dev/tty[7-9] crw-rw---- 1 root uucp 4, 64 May 2 08:45 /dev/ttyS[0-4] crw------- 1 root uucp 4, 68 May 2 08:45 /dev/ttyS[4-7] crw-rw-rw- 1 root tty 3, 0 May 25 04:58 /dev/ttyp0 crw-r--r-- 1 root root 1, 9 May 25 04:58 /dev/urandom crw--w---- 1 root tty 7, 0 May 25 04:58 /dev/vcs crw-rw---- 1 root tty 7, 1 May 25 04:58 /dev/vcs1 crw-rw---- 1 root tty 7, 129 May 25 04:58 /dev/vcsa1 crw--w---- 1 root tty 7, 130 May 25 04:58 /dev/vcsa2 pr-------- 1 uwe tty 0 May 25 05:01 /dev/xconsole crw-rw-rw- 1 root root 1, 5 May 2 08:45 /dev/zeroNice: /root has mode 700. Um, /dev/fd0, /dev/hdd, and a few others are owned by me (user "uwe")? Why?
at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash bin:x:1:1:bin:/bin:/bin/bash daemon:x:2:2:Daemon:/sbin:/bin/bash ftp:x:40:49:FTP account:/srv/ftp:/bin/bash games:x:12:100:Games account:/var/games:/bin/bash haldaemon:x:101:102:User for haldaemon:/var/run/hal:/bin/false lp:x:4:7:Printing daemon:/var/spool/lpd:/bin/bash mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false man:x:13:62:Manual pages viewer:/var/cache/man:/bin/bash mdnsd:x:78:65534:mDNSResponder runtime user:/var/lib/mdnsd:/bin/false messagebus:x:100:101:User for D-BUS:/var/run/dbus:/bin/false news:x:9:13:News system:/etc/news:/bin/bash nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash ntp:x:74:103:NTP daemon:/var/lib/ntp:/bin/false postfix:x:51:51:Postfix Daemon:/var/spool/postfix:/bin/false root:x:0:0:root:/root:/bin/bash sshd:x:71:65:SSH daemon:/var/lib/sshd:/bin/false suse-ncc:x:102:104:Novell Customer Center User:/var/lib/YaST2/suse-ncc-fakehome:/bin/bash uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash wwwrun:x:30:8:WWW daemon apache:/var/lib/wwwrun:/bin/false uwe:x:1000:100::/home/uwe:/bin/bashQuite a random mix of /bin/bash and /bin/false as shells, it seems. Notice the absence of /bin/sh.
# find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -ld ' ' \; -rwsr-xr-x 1 root root 31668 Apr 23 08:48 /bin/su -rwsr-xr-x 1 root root 35520 Apr 23 03:53 /bin/ping -rwsr-xr-x 1 root audio 20252 Apr 23 04:21 /bin/eject -rwsr-xr-x 1 root root 321981 May 2 08:50 /bin/mount -rwsr-xr-x 1 root root 31696 Apr 23 03:53 /bin/ping6 -rwsr-xr-x 1 root root 117887 May 2 08:50 /bin/umount -rwsr-xr-x 1 root root 5056 May 2 11:14 /opt/kde3/bin/artswrapper -rwsr-xr-x 1 root root 6696 May 2 12:02 /opt/kde3/bin/kpac_dhcp_helper -rwsr-xr-x 1 root trusted 43940 May 2 09:47 /usr/bin/at -rwsr-xr-x 1 root root 836524 May 2 10:28 /usr/bin/gpg -rwsr-xr-x 2 root root 4880 Apr 23 05:09 /usr/bin/man -rwsr-xr-x 1 root root 18720 Apr 23 04:32 /usr/bin/rcp -rwsr-xr-x 1 root root 9340 Apr 23 04:32 /usr/bin/rsh -rwsr-xr-x 1 root shadow 73284 May 2 10:50 /usr/bin/chfn -rwsr-xr-x 1 root shadow 68992 May 2 10:50 /usr/bin/chsh -rwsr-xr-x 1 root root 105084 May 2 09:47 /usr/bin/sudo -rwxr-sr-x 1 root tty 10312 May 2 08:50 /usr/bin/wall -rwsr-xr-x 1 lp sys 10400 Apr 25 19:15 /usr/bin/lppasswd -rwsr-xr-x 1 root trusted 33260 Apr 23 04:36 /usr/bin/crontab -rwsr-xr-x 1 root root 59980 May 2 16:38 /usr/bin/fileshareset -rwsr-xr-x 1 root shadow 75692 May 2 10:50 /usr/bin/chage -rwsr-xr-x 2 root root 4880 Apr 23 05:09 /usr/bin/mandb -rwxr-sr-x 1 root tty 8936 May 2 08:50 /usr/bin/write -rwsr-xr-x 1 root shadow 13388 May 2 10:50 /usr/bin/expiry -rwsr-xr-x 1 root root 15532 May 2 10:50 /usr/bin/newgrp -rwsr-xr-x 1 root shadow 72836 May 2 10:50 /usr/bin/passwd -rwsr-xr-x 1 root shadow 74528 May 2 10:50 /usr/bin/gpasswd -rwsr-xr-x 1 root root 12900 Apr 23 04:32 /usr/bin/rlogin -rwsr-xr-x 1 root root 23990 Apr 29 01:08 /usr/lib/pt_chown -rwxr-sr-x 1 root maildrop 10440 May 2 09:36 /usr/sbin/postdrop -rwxr-sr-x 1 root maildrop 10444 May 2 09:36 /usr/sbin/postqueue -rwxr-sr-x 1 root tty 7288 Apr 23 03:40 /usr/sbin/utempter -rws--x--x 1 root root 1832764 May 2 09:26 /usr/X11R6/bin/Xorg -rwxr-sr-x 1 root shadow 20136 Apr 23 03:54 /sbin/unix_chkpwd -rwsr-x--- 1 root dialout 31700 May 2 09:56 /sbin/isdnctrl -rwxr-sr-x 1 root shadow 6624 Apr 23 04:35 /sbin/unix2_chkpwdQuite a bunch... I sure hope those "rsh", "rcp", "rlogin", and so on, are ssh aliases in reality (didn't check)...
# find / -not -type l -perm -o+w -exec ls -ld ' ' \; srw-rw-rw- 1 root root 0 May 25 23:54 /dev/log crw-rw-rw- 1 root root 1, 5 May 2 08:45 /dev/zero crw-rw-rw- 1 root tty 5, 0 May 2 08:45 /dev/tty crw-rw-rw- 1 root tty 5, 2 May 26 00:02 /dev/ptmx crw-rw-rw- 1 root root 1, 3 May 2 08:45 /dev/null crw-rw-rw- 1 root tty 2, 0 May 25 23:54 /dev/ptyp* crw-rw-rw- 1 root tty 3, 0 May 25 23:54 /dev/ttyp* crw--w--w- 1 root root 1, 7 May 25 23:54 /dev/full crw-rw-rw- 1 root root 1, 8 May 25 23:54 /dev/random drwxrwxrwt 3 root root 60 May 25 23:54 /dev/shm crw-rw-rw- 1 root tty 5, 0 May 2 08:45 /lib/udev/devices/tty crw-rw-rw- 1 root root 1, 3 May 2 08:45 /lib/udev/devices/null crw-rw-rw- 1 root tty 5, 2 May 2 08:45 /lib/udev/devices/ptmx crw-rw-rw- 1 root root 1, 5 May 2 08:45 /lib/udev/devices/zero drwxrwxrwt 10 root root 672 May 26 00:02 /tmp drwxrwxrwt 2 root root 48 Apr 23 03:51 /tmp/.ICE-unix drwxrwxrwt 2 root root 72 May 25 23:54 /tmp/.X11-unix srwxrwxrwx 1 root root 0 May 25 23:54 /tmp/.X11-unix/X0 srw-r--rw- 1 root root 0 May 25 23:54 /var/run/zmd/zmd-web.socket srwxrwxrwx 1 root root 0 May 25 23:54 /var/run/zmd/zmd-remoting.socket srwxrwxrwx 1 root root 0 May 25 23:54 /var/run/dbus/system_bus_socket srw-rw-rw- 1 root root 0 May 25 23:54 /var/run/nscd/socket srwxrwxrwx 1 root root 0 May 25 23:54 /var/run/mdnsd srw-rw-rw- 1 root root 0 May 25 23:54 /var/run/.resmgr_socket drwxrwxrwt 2 root root 48 May 25 23:54 /var/run/uscreens drwxrwxrwt 11 root root 416 May 25 23:55 /var/tmp drwxrwxrwt 2 root root 48 Apr 23 03:51 /var/tmp/vi.recover drwxrwxrwt 2 root root 48 Apr 23 03:51 /var/cache/fonts drwxrwxrwt 2 root root 48 Apr 23 03:51 /var/spool/mail prw--w--w- 1 postfix postfix 0 May 25 23:59 /var/spool/postfix/public/qmgr srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/public/flush srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/public/showq prw--w--w- 1 postfix postfix 0 May 26 00:02 /var/spool/postfix/public/pickup srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/public/cleanup srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/lmtp srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/smtp srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/uucp srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/rewrite srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/discard srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/anvil srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/bsmtp srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/defer srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/cyrus srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/error srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/local srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/relay srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/trace srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/maildrop srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/bounce srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/ifmail srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/scache srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/verify srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/virtual srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/procmail srw-rw-rw- 1 postfix postfix 0 May 25 23:54 /var/spool/postfix/private/proxymap drwxrwxrwt 8 root root 192 May 25 00:06 /usr/src/packages/RPMS drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/i386 drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/i486 drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/i586 drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/i686 drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/athlon drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/RPMS/noarch drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/BUILD drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/SPECS drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/SRPMS drwxrwxrwt 2 root root 48 Apr 23 02:28 /usr/src/packages/SOURCESNo real files actually, only sockets, device files, and directories. Still, it's quite a lot of them. Do they all really need to be world-writable?
Class klass = this.getClass();We can then look up the method we are looking for using Class.getMethod, but this function requires an array of types that the method we are looking for takes as parameters, so we get the right version of an overloaded method. We can do this with:
Class[] arguments = Int.class, String.class, URL.class ; Method method = klass.getMethod("foo", arguments);Now we have our method, we can call it using the Method.invoke() call. This takes an object as the first parameter, which we can use this, and an array of Objects for the parameters.
Object[] values = bar, baz, quux ; method.invoke(this, values);But what happens if our class has no member method called foo()? Well, Class.getMethod() will throw a NoSuchMethodException, so we can just throw a try/catch block around the code to deal with unhandled functions. It's worth pointing out that Class.getMethod() also throws SecurityException and Method.invoke() throws IllegalAccessException, IllegalArgumentException and InvocationTargetException, so you'll want to catch Exception too. We can chain some of these calls together and the result for my SAX parser is:
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException try Class[] argTypes = String.class, String.class, String.class, Attributes.class ; Object[] values = uri, localName, qName, atts ; this.getClass().getMethod("startElement_" + localName, argTypes) .invoke(this, values); catch (NoSuchMethodException e) log.debug("unhandled element " + localName); catch (Exception e) e.printStackTrace();With this arrangement, when I want to handle a new element in my code I can just make a function like:
public void startElement_foo(String uri, String localName, String qName, Attributes atts) throws SAXException ...
'(conjure cc)
is a child of the logger named '(conjure)
.
This may all sound overly complicated, but getting started is very straightforward:
;; ,open spells.logging
(define log-info (make-log ‘(test) ‘info))
(configure-logger ‘())
(log-info “hello world!”)
make-log
creates a logging procedure. Logging procedures take a single argument to be logged; the argument may be an arbitrary object; it is up to the handlers on how to go about formatting this object. The argument passed to the logging procedure is wrapped in a log entry, which additionally contains the log level.
The name of the logger that is to be used is '(test)
, and 'info
is the log level. If the logger '(test)
doesn’t already exist, it is created on the fly with no handlers and the root logger as a parent; it can be configured later. This separation of logger creation and configuration is important: In a real application, the logging can be configured from the command line or a configuration file; you don’t want to (hard-)code it into the same module that uses the logger.
(configure-logger '())
configures the root logger (which has the empty list as name) with a default configuration. configure-logger
also has an optional argument in which you can provide a custom configuration, but I won’t go into this now, since this part of interface is most likely to change. The default configuration amounts to logging everything on (current-output-port)
.
Finally, we log a simple string through the logging procedure log-info
. The output looks like this:
(test: [info] hello world!)
Well, enough of this for now; if you got curious you can take peek at the code.
Summertime, and the learning is easy. Our problem is structured,[*] sung “sharpee”
And the accuracy is high. Your funders are rich,
And your colleagues are good-looking. So grow little margin,
We gonna solve AI. Wintertime, and the learning is #-P. Our speech is recognized,
But we don’t know why. Our code is in MATLAB,
And our data’s synthetic. So grow little margin,
We gonna solve AI.
Next.